﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.Data.OleDb;
using System.Collections.ObjectModel;
using System.ComponentModel;
using libConn;
using Microsoft.Win32;
using System.IO;
using CodeReason.Reports;
using System.Windows.Xps.Packaging;

namespace ApartmentSale
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void mainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            FILEPATH = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\ApartmentSales\" +  "database.accdb";

            if (!DatabaseInit())
            {
                this.Close();
                return;
            }

            RefleshDataView();
            RefleshFindArea();
            RefleshApartmentEdit();
            getBitRule();
            ChangeWindowState();

            currentApartment = new ApartmentView();
            currentContract = new ContractView();
        }

        private void mainWindow_Closed(object sender, EventArgs e)
        {
            string str = "";
            libConn.AccdbConn.disconn(ref str);

            if (str != "")
                MessageBox.Show(str);
        }

        private void miHelp_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://code.google.com/p/apartmentsales/w/list");
        }

        private void miAbout_Click(object sender, RoutedEventArgs e)
        {
            About about = new About();
            about.ShowDialog();
        }

        private void RefleshFindArea()
        {
            FillDataToComboBox(cbFindCode, "apartments", "apartment_code", true);
            FillDataToComboBox(cbFindBuild, "apartments", "apartment_building", false);
            FillDataToComboBox(cbFindName, "apartments", "apartment_host_name", false);
        }

        private void ChangeWindowState()
        {
            switch (operation)
            {
                case Operation.None:
                    tiList.IsEnabled = true;
                    tiBasic.IsEnabled = false;
                    tiFinancial.IsEnabled = false;
                    tiReceipt.IsEnabled = false;
                    tiInvoice.IsEnabled = false;
                    tiContract.IsEnabled = false;
                    tiDiscription.IsEnabled = false;

                    lbApartmentBasic.Content = "";
                    btSave.IsEnabled = false;
                    btCancel.IsEnabled = false;

                    lbApartmentFinancial.Content = "";
                    btFinancialSave.IsEnabled = false;
                    btFinancialCancel.IsEnabled = false;

                    lbContract.Content = "";
                    btContractSave.IsEnabled = false;
                    btContractCancel.IsEnabled = false;

                    lbApartmentDiscription.Content = "";
                    btDiscriptionSave.IsEnabled = false;
                    btDiscriptionCancel.IsEnabled = false;
                    break;
                case Operation.View:
                    tiList.IsEnabled = true;
                    tiBasic.IsEnabled = true;
                    tiReceipt.IsEnabled = true;
                    tiInvoice.IsEnabled = true;
                    tiDiscription.IsEnabled = true;

                    if (currentApartment.apartment_status == 2)
                    {
                        tiFinancial.IsEnabled = true;
                        tiContract.IsEnabled = true;
                    }
                    else
                    {
                        tiFinancial.IsEnabled = false;
                        tiContract.IsEnabled = false;
                    }

                    if (currentApartment.apartment_payment_term == 2)
                    {
                        tbApartmentPaymentBankAmount.IsEnabled = true;
                        tbApartmentPaymentBankIncome.IsEnabled = true;
                    }
                    else
                    {
                        tbApartmentPaymentBankAmount.IsEnabled = false;
                        tbApartmentPaymentBankIncome.IsEnabled = false;
                    }

                    lbApartmentBasic.Content = "";
                    btSave.IsEnabled = false;
                    btCancel.IsEnabled = false;

                    lbApartmentFinancial.Content = "";
                    btFinancialSave.IsEnabled = false;
                    btFinancialCancel.IsEnabled = false;

                    lbContract.Content = "";
                    btContractSave.IsEnabled = false;
                    btContractCancel.IsEnabled = false;
                    cbContractStatus.IsEnabled = true;

                    lbApartmentDiscription.Content = "";
                    btDiscriptionSave.IsEnabled = false;
                    btDiscriptionCancel.IsEnabled = false;

                    break;
                case Operation.Create:
                    tiList.IsEnabled = false;
                    tiBasic.IsEnabled = true;
                    tiFinancial.IsEnabled = false;
                    tiReceipt.IsEnabled = false;
                    tiInvoice.IsEnabled = false;
                    tiContract.IsEnabled = false;
                    tiDiscription.IsEnabled = false;

                    lbApartmentBasic.Content = "Creating a new apartment item.";
                    btSave.IsEnabled = true;
                    btCancel.IsEnabled = true;
                    break;
                case Operation.Update:
                    tiList.IsEnabled = false;
                    tiBasic.IsEnabled = true;
                    if (currentApartment.apartment_status == 2)
                    {
                        tiFinancial.IsEnabled = true;
                        lbApartmentFinancial.Content = "Information has been modified, please save it.";
                        btFinancialSave.IsEnabled = true;
                        btFinancialCancel.IsEnabled = true;
                    }
                    tiReceipt.IsEnabled = false;
                    tiInvoice.IsEnabled = false;
                    tiContract.IsEnabled = false;
                    tiDiscription.IsEnabled = true;

                    lbApartmentBasic.Content = "Information has been modified, please save it.";
                    btSave.IsEnabled = true;
                    btCancel.IsEnabled = true;

                    lbApartmentDiscription.Content = "Information has been modified, please save it.";
                    btDiscriptionSave.IsEnabled = true;
                    btDiscriptionCancel.IsEnabled = true;
                    break;
                case Operation.ContractCreate:
                    tiList.IsEnabled = false;
                    tiBasic.IsEnabled = false;
                    tiFinancial.IsEnabled = false;
                    tiReceipt.IsEnabled = false;
                    tiInvoice.IsEnabled = false;
                    tiContract.IsEnabled = true;
                    tiDiscription.IsEnabled = false;

                    lbContract.Content = "Creating a new contract.";
                    btContractSave.IsEnabled = true;
                    btContractCancel.IsEnabled = true;

                    cbContractStatus.IsEnabled = false;
                    break;
                case Operation.ContractUpdate:
                    tiList.IsEnabled = false;
                    tiBasic.IsEnabled = false;
                    tiFinancial.IsEnabled = false;
                    tiReceipt.IsEnabled = false;
                    tiInvoice.IsEnabled = false;
                    tiContract.IsEnabled = true;
                    tiDiscription.IsEnabled = false;

                    lbContract.Content = "Contract has been modified, please save it.";
                    btContractSave.IsEnabled = true;
                    btContractCancel.IsEnabled = true;

                    cbContractStatus.IsEnabled = true;
                    break;
            }
        }

        private String FILEPATH;
        private String errMessage = "";

        public enum Operation { None, View, Create, Update, ContractCreate, ContractUpdate}
        private Operation operation = Operation.None;

        void cmdApartmentCode_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			DiaCode dialog = new DiaCode();
			dialog.ShowDialog();
		}

        void cmdApartmentNew_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (operation == Operation.None || operation == Operation.View)
            {
                operation = Operation.Create;
                ChangeWindowState();
                tiBasic.IsSelected = true;
                currentApartment = new ApartmentView();
                currentApartment.PropertyChanged += new PropertyChangedEventHandler(currentApartment_PropertyChanged);
                this.DataContext = currentApartment;
            }
        }

        void cmdAffirmance_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Affirmance dialog = new Affirmance();
            dialog.Owner = this;
            dialog.ShowDialog();
            RefleshDataView();
        }

        void cmdAffirmanceRule_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AffirmanceRule dialog = new AffirmanceRule();
            dialog.ShowDialog();
        }

        void cmdDeposit_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Deposit dialog = new Deposit();
            dialog.ShowDialog();
            RefleshDataView();
        }

        void cmdManager_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Manager dialog = new Manager();
            dialog.ShowDialog();
        }

        void cmdContract_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (operation == Operation.None || operation == Operation.View)
            {
                if (dataGrid.SelectedIndex == -1)
                {
                    MessageBox.Show("Please select the room number, and then view the contract information.",
                        "Notice", MessageBoxButton.OK, MessageBoxImage.Stop);
                    return;
                }

                if (currentApartment.apartment_status != 2)
                {
                    getManager();

                    operation = Operation.ContractCreate;
                    ChangeWindowState();

                    contract_has_loaded = true;
                    currentContract = new ContractView();
                    currentContract.apartment_id = currentApartment.apartment_id;

                    tbContractPaymentDebateRate.Text = String.Format("{0:N2}", currentContract.payment_rate);

                    tbManagerDebateRate.Text = String.Format("{0:N2}", 1);
                    currentContract.manager_debate_rate = 1;

                    currentContract.PropertyChanged += new PropertyChangedEventHandler(currentContract_PropertyChanged);
                    tiContract.DataContext = currentContract;
                }

                tiContract.IsSelected = true;
            }
        }

        void cmdBackup_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SaveFileDialog dlgSaveFile = new SaveFileDialog();
            dlgSaveFile.Filter = "Database File(*.accdb)|*.accdb";
            dlgSaveFile.Title = "Database Backup";
            dlgSaveFile.DefaultExt = "accdb";
            dlgSaveFile.AddExtension = true;
            dlgSaveFile.CheckPathExists = true;

            string filepath;

            bool? result;
            result = dlgSaveFile.ShowDialog();

            if (result != null && (bool)result)
            {
                filepath = dlgSaveFile.FileName;
            }
            else
            {
                return;
            }

            try
            {
                string errMessage = "";
                libConn.AccdbConn.disconn(ref errMessage);

                File.Copy(FILEPATH, filepath, true);

                if (!DatabaseInit())
                {
                    this.Close();
                }

                RefleshDataView();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
        }

        void cmdRestory_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            OpenFileDialog filedialog = new OpenFileDialog();
            filedialog.Title = "Restory Database";
            filedialog.Filter = "Database File(*.accdb)|*.accdb";
            filedialog.DefaultExt = "accdb";
            filedialog.AddExtension = true;
            filedialog.CheckFileExists = true;
            filedialog.CheckPathExists = true;
            filedialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            string filepath;

            bool? result;
            result = filedialog.ShowDialog();

            if (result != null && (bool)result)
            {
                filepath = filedialog.FileName;
            }
            else
            {
                return;
            }

            try
            {
                string errMessage = "";
                libConn.AccdbConn.disconn(ref errMessage);

                File.Copy(filepath, FILEPATH, true);


                if (!DatabaseInit())
                {
                    this.Close();
                }

                RefleshDataView();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
        }

        void cmdGeneralReport_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ReceiptReport dialog = new ReceiptReport(ReceiptReport.ViewType.Day);
            dialog.Show();
        }

        void cmdSaleReport_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ReceiptReport dialog = new ReceiptReport(ReceiptReport.ViewType.Month);
            dialog.ShowDialog();
        }

        void cmdReceipt_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Receipt dialog = new Receipt();
            dialog.Show();
        }

        void cmdInvoice_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Invoice dialog = new Invoice();
            dialog.Show();
        }

        void cmdPrint_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            btPrint_Click(sender, e);
        }

        private bool DatabaseInit()
        {
            errMessage = null;

            libConn.AccdbConn.conn(FILEPATH, ref errMessage);

            if (errMessage != null)
            {
                if (errMessage.IndexOf("Microsoft.ACE.OLEDB.12.0") > 0)
                {
                    frmAccess2007 dialog = new frmAccess2007();
                    dialog.ShowDialog();
                }
                else
                {
                    System.Windows.MessageBox.Show(
                         errMessage,
                         "Database connection failed",
                         System.Windows.MessageBoxButton.OK,
                         System.Windows.MessageBoxImage.Error);
                }

                return false;
            }

            return true;
        }

        private bool FillDataToComboBox(ComboBox cb, String tableName, String itemName, Boolean repeat)
        {
            errMessage = null;

            string str = "SELECT " + itemName;
            str += " FROM " + tableName;
            if(!repeat)
                str += " GROUP BY " + itemName; 
            str += " ORDER BY " + itemName;

            cb.Items.Clear();

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Update " + itemName + " failed",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            if (oleDT.Rows.Count < 1)
            {
                return true;
            }

            foreach (DataRow r in oleDT.Rows)
            {
                cb.Items.Add(r[0]);
            }

            return true;
        }

        private DataTable GetDataTable()
        {
            DataTable table = new DataTable("Data Table");

            DataColumn column;

            column = new DataColumn();
            column.DataType = Type.GetType("System.Int32");
            column.ColumnName = "apartment_id";
            column.AutoIncrement = false;
            column.Caption = "ID";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);

            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_status";
            column.AutoIncrement = false;
            column.Caption = "Status";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);

            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_code";
            column.Caption = "Code";
            column.ReadOnly = true;
            column.Unique = true;
            table.Columns.Add(column);

            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_building";
            column.AutoIncrement = false;
            column.Caption = "Building";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_floor";
            column.AutoIncrement = false;
            column.Caption = "Floor";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
          
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_unit";
            column.AutoIncrement = false;
            column.Caption = "Unit";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_sn";
            column.AutoIncrement = false;
            column.Caption = "SN";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_built_area";
            column.AutoIncrement = false;
            column.Caption = "Building Area";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_public_area";
            column.AutoIncrement = false;
            column.Caption = "Public Area";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_area";
            column.AutoIncrement = false;
            column.Caption = "Total Area";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_price";
            column.AutoIncrement = false;
            column.Caption = "Price";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_total";
            column.AutoIncrement = false;
            column.Caption = "Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_decorating";
            column.AutoIncrement = false;
            column.Caption = "Decorating";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_decorating_price";
            column.AutoIncrement = false;
            column.Caption = "Decorating Price";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_decorating_total";
            column.AutoIncrement = false;
            column.Caption = "Decorating Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_rebate_amount";
            column.AutoIncrement = false;
            column.Caption = "Rebate Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_accounts_due";
            column.AutoIncrement = false;
            column.Caption = "Total Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_invoice_amount";
            column.AutoIncrement = false;
            column.Caption = "Invoice Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_payment_term";
            column.AutoIncrement = false;
            column.Caption = "Payment Terms";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_payment_status";
            column.AutoIncrement = false;
            column.Caption = "Payment Status";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_payment_amount";
            column.AutoIncrement = false;
            column.Caption = "Payment Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_payment_paid_amount";
            column.AutoIncrement = false;
            column.Caption = "Paid Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_payment_unpaid_amount";
            column.AutoIncrement = false;
            column.Caption = "Unpaid Amount";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_payment_bank_amount";
            column.AutoIncrement = false;
            column.Caption = "Amount of Loans";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.Double");
            column.ColumnName = "apartment_payment_bank_income";
            column.AutoIncrement = false;
            column.Caption = "Paid of Loans";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_host_name";
            column.AutoIncrement = false;
            column.Caption = "Custom Name";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_host_contact";
            column.AutoIncrement = false;
            column.Caption = "Custom Contact";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);
            
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "apartment_discription";
            column.AutoIncrement = false;
            column.Caption = "Resume";
            column.ReadOnly = false;
            column.Unique = false;
            
            table.Columns.Add(column);

            DataColumn[] PrimaryKeyColumns = new DataColumn[1];
            PrimaryKeyColumns[0] = table.Columns["apartment_id"];
            table.PrimaryKey = PrimaryKeyColumns;

            try
            {
                foreach (ApartmentView apartment in dataGrid.Items)
                {
                    DataRow r = table.NewRow();
                    r["apartment_id"] = apartment.apartment_id;
                    r["apartment_status"] = apartment.status_string;
                    r["apartment_code"] = apartment.apartment_code;
                    r["apartment_building"] = apartment.apartment_building;
                    r["apartment_floor"] = apartment.apartment_floor;
                    r["apartment_unit"] = apartment.apartment_unit;
                    r["apartment_sn"] = apartment.apartment_sn;
                    r["apartment_built_area"] = apartment.apartment_built_area;
                    r["apartment_public_area"] = apartment.apartment_public_area;
                    r["apartment_area"] = apartment.apartment_area;
                    r["apartment_price"] = apartment.apartment_price;
                    r["apartment_total"] = apartment.apartment_total;
                    r["apartment_decorating"] = apartment.apartment_decorating ? "有" : "无";
                    r["apartment_decorating_price"] = apartment.apartment_decorating_price;
                    r["apartment_decorating_total"] = apartment.apartment_decorating_total;
                    r["apartment_rebate_amount"] = apartment.apartment_rebate_amount;
                    r["apartment_accounts_due"] = apartment.apartment_accounts_due;
                    r["apartment_invoice_amount"] = apartment.apartment_invoice_amount;
                    r["apartment_payment_term"] = apartment.payment_term;
                    r["apartment_payment_status"] = apartment.payment_status;
                    r["apartment_payment_amount"] = apartment.apartment_payment_amount;
                    r["apartment_payment_paid_amount"] = apartment.apartment_payment_paid_amount;
                    r["apartment_payment_unpaid_amount"] = apartment.apartment_payment_unpaid_amount;
                    r["apartment_payment_bank_amount"] = apartment.apartment_payment_bank_amount;
                    r["apartment_payment_bank_income"] = apartment.apartment_payment_bank_income;
                    r["apartment_host_name"] = apartment.apartment_host_name;
                    r["apartment_host_contact"] = apartment.apartment_host_contact;
                    r["apartment_discription"] = apartment.apartment_discription;

                    table.Rows.Add(r);
                }

                DataRow sumRow = table.NewRow();
                sumRow["apartment_id"] = -1;
                sumRow["apartment_code"] = "Sum";

                sumRow["apartment_built_area"] = table.Compute("sum(apartment_built_area)","true");
                sumRow["apartment_public_area"] = table.Compute("sum(apartment_public_area)", "true");
                sumRow["apartment_area"] = table.Compute("sum(apartment_area)", "true");
                sumRow["apartment_total"] = table.Compute("sum(apartment_total)", "true");
                sumRow["apartment_decorating_total"] = table.Compute("sum(apartment_decorating_total)", "true");
                sumRow["apartment_rebate_amount"] = table.Compute("sum(apartment_rebate_amount)", "true");
                sumRow["apartment_accounts_due"] = table.Compute("sum(apartment_accounts_due)", "true");
                sumRow["apartment_invoice_amount"] = table.Compute("sum(apartment_invoice_amount)", "true");
                sumRow["apartment_payment_amount"] = table.Compute("sum(apartment_payment_amount)", "true");
                sumRow["apartment_payment_paid_amount"] = table.Compute("sum(apartment_payment_paid_amount)", "true");
                sumRow["apartment_payment_unpaid_amount"] = table.Compute("sum(apartment_payment_unpaid_amount)", "true");
                sumRow["apartment_payment_bank_amount"] = table.Compute("sum(apartment_payment_bank_amount)", "true");
                sumRow["apartment_payment_bank_income"] = table.Compute("sum(apartment_payment_bank_income)", "true");
                table.Rows.Add(sumRow);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return null;
            }

            return table;
        }

        private void RefleshSummary(int iTotal, int iForsale, int iDeposited, int iSaled,
            double dArea, double dTotalSum, double dPaid, double dUnpaid)
        {
            lbTotal.Content = iTotal.ToString();
            lbForsale.Content = iForsale.ToString();
            lbDeposited.Content = iDeposited.ToString();
            lbSaled.Content = iSaled.ToString();
            lbAreaSum.Content = String.Format("{0:N2}", dArea);
            lbTotalSum.Content = String.Format("{0:N2}", dTotalSum);
            lbPaidSum.Content = String.Format("{0:N2}", dPaid);
            lbUnpaidSum.Content = String.Format("{0:N2}", dUnpaid);
        }

        public void RefleshDataView()
        {
            string emptyString = "";
            RefleshDataView(emptyString);
        }

        public void RefleshDataView(String findStr)
        {
            errMessage = null;
            string str = "SELECT * FROM apartments";

            if (findStr.Length != 0)
            {
                str += findStr;
            }

            str += " ORDER BY apartment_code";

            int iTotal = 0;
            int iForsale = 0;
            int iDeposited = 0;
            int iSaled = 0;
            double dArea = 0;
            double dTotalSum = 0;
            double dPaid = 0;
            double dUnpaid = 0;

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Refresh list failed.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return;
            }

            iTotal = oleDT.Rows.Count;

            ObservableCollection<ApartmentView> apartments = new ObservableCollection<ApartmentView>();

            foreach (DataRow r in oleDT.Rows)
            {
                if (!r.IsNull("apartment_status"))
                {
                    switch (Convert.ToInt32(r["apartment_status"]))
                    {
                        case 0:
                            iForsale++;
                            break;
                        case 1:
                            iDeposited++;
                            break;
                        case 2:
                            iSaled++;
                            break;
                    }
                }
                else
                {
                    System.Windows.MessageBox.Show(
                        "Refresh state, the emergence of the value is empty.",
                        "Refresh list failed",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return;
                }

                try
                {
                    ApartmentView a = new ApartmentView(r);
                    apartments.Add(a);
                    dArea += a.apartment_area;
                    dTotalSum += a.apartment_total;
                    dPaid += a.apartment_payment_paid_amount;
                    dUnpaid += a.apartment_payment_unpaid_amount;
                }
                catch(Exception ex)
                {
                    System.Windows.MessageBox.Show(
                        ex.Message,
                        "Refresh list failed",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return;
                }
            }

            dataGrid.DataContext = apartments;

            RefleshSummary(iTotal, iForsale, iDeposited, iSaled, dArea, dTotalSum, dPaid, dUnpaid);

        }

        private void dataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (dataGrid.SelectedIndex == -1)
                return;

            var apartment = dataGrid.SelectedItem as ApartmentView;
            if (apartment != null)
            {
                currentApartment = (ApartmentView)apartment.Clone();
                currentApartment.PropertyChanged += new PropertyChangedEventHandler(currentApartment_PropertyChanged);
                this.DataContext = currentApartment;

                getContract(currentApartment.apartment_id);
                getReceipt(currentApartment.apartment_id);
                getInvoice(currentApartment.apartment_id);

                operation = Operation.View;
                ChangeWindowState();
            }
            else
            {
                operation = Operation.None;
                ChangeWindowState();
            }
        }

        private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (dataGrid.SelectedIndex == -1)
                return;

            var apartment = dataGrid.SelectedItem as ApartmentView;
            if (apartment != null)
            {
                currentApartment = (ApartmentView)apartment.Clone();
                currentApartment.PropertyChanged += new PropertyChangedEventHandler(currentApartment_PropertyChanged);
                this.DataContext = currentApartment;

                if (currentApartment.apartment_status == 2)
                {
                    getContract(currentApartment.apartment_id);
                }
                getReceipt(currentApartment.apartment_id);
                getInvoice(currentApartment.apartment_id);

                operation = Operation.View;
                ChangeWindowState();
            }
            else
            {
                operation = Operation.None;
                ChangeWindowState();
            }
        }

        private bool deleteData(string code)
        {
            string errMessage = null;
            string str = "DELETE FROM apartments WHERE apartment_code = '" + code.Replace("'", "''") + "'";

            libConn.AccdbConn.exec(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failed to delete item.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }
            return true;
        }

        private void btFind_Click(object sender, RoutedEventArgs e)
        {
            String str = " WHERE apartment_code LIKE ";
            if (cbFindCode.Text.Length == 0)
            {
                str += "'%'";
            }
            else
            {
                str += "'%" + cbFindCode.Text + "%'";
            }

            if (cbFindBuild.Text.Length == 0)
            {
                str += " AND apartment_building LIKE '%'";
            }
            else
            {
                str += " AND apartment_building LIKE '%" + cbFindBuild.Text + "%'";
            }

            if (cbFindStatus.SelectedIndex == -1)
            {
                str += " AND apartment_status LIKE '%'";
            }
            else
            {
                str += " AND apartment_status LIKE '%" + cbFindStatus.SelectedIndex + "%'";
            }

            if (cbFindName.Text.Length == 0)
            {
                str += " AND apartment_host_name LIKE '%'";
            }
            else
            {
                str += " AND apartment_host_name LIKE '%" + cbFindName.Text + "%'";
            }

            RefleshDataView(str);
            operation = Operation.None;
            ChangeWindowState();
        }

        private void btFindClear_Click(object sender, RoutedEventArgs e)
        {
            cbFindCode.SelectedIndex = -1;
            cbFindCode.Text = "";
            cbFindBuild.SelectedIndex = -1;
            cbFindBuild.Text = "";
            cbFindStatus.SelectedIndex = -1;
            cbFindName.SelectedIndex = -1;
            cbFindName.Text = "";

            RefleshDataView();
            operation = Operation.None;
            ChangeWindowState();
        }

        private void miDelete_Click(object sender, RoutedEventArgs e)
        {
            if (dataGrid.SelectedIndex == -1)
                return;

            var apartment = dataGrid.SelectedItem as ApartmentView;
            if (apartment != null)
            {
                if (apartment.apartment_status != 0)
                {
                    MessageBox.Show("Can not be ordered or sold directly to remove the housing information."
                        + " Please remove the deposit records or contracts related records.");
                    return;
                }

                if (MessageBox.Show("Sure you want to delete code is " + apartment.apartment_code + 
                    " for housing information?\nThis action can not be recovered!",
                    "Delete", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    if (deleteData(apartment.apartment_code))
                        RefleshDataView();
                }
            }
        }

        private void btDelete_Click(object sender, RoutedEventArgs e)
        {
            if (dataGrid.SelectedIndex == -1)
                return;

            var apartment = dataGrid.SelectedItem as ApartmentView;
            if (apartment != null)
            {
                if (apartment.apartment_status != 0)
                {
                    MessageBox.Show("Can not be ordered or sold directly to remove the housing information."
                        + " Please remove the deposit records or contracts related records.");
                    return;
                }

                if (MessageBox.Show("Sure you want to delete code is " + apartment.apartment_code + 
                    " for housing information?\nThis action can not be recovered!",
                    "Delete", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    if (deleteData(apartment.apartment_code))
                        RefleshDataView();
                }
            }

        }

        private void btPrint_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                this.Cursor = Cursors.AppStarting;
                ReportDocument reportDocument = new ReportDocument();

                StreamReader reader = new StreamReader(new FileStream(@"Templates\SimpleReport.xaml", FileMode.Open, FileAccess.Read));
                reportDocument.XamlData = reader.ReadToEnd();
                reportDocument.XamlImagePath = System.IO.Path.Combine(Environment.CurrentDirectory, @"Templates\");
                reader.Close();

                ReportData data = new ReportData();

                data.ReportDocumentValues.Add("PrintDate", DateTime.Now);

                DataTable table = GetDataTable();

                data.DataTables.Add(table);

                XpsDocument xps = reportDocument.CreateXpsDocument(data);

                ReportPreview dialog = new ReportPreview();
                dialog.DocView.Document = xps.GetFixedDocumentSequence();

                dialog.Title = "Apartment List";

                this.Cursor = Cursors.Arrow;
                dialog.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n\r\n" + ex.GetType() + "\r\n" + ex.StackTrace, ex.GetType().ToString(), MessageBoxButton.OK, MessageBoxImage.Stop);
            }
        }

        private void btDeposit_Click(object sender, RoutedEventArgs e)
        {
            if (dataGrid.SelectedIndex == -1)
            {
                MessageBox.Show("Please select housing information, and then add the order.");
            }

            ApartmentView apartment = dataGrid.SelectedItem as ApartmentView;
            if (apartment == null)
            {
                return;
            }

            if (apartment.apartment_status != 0)
            {
                tiReceipt.IsSelected = true;
            }
            else
            {
                DepositEdit dialog = new DepositEdit(apartment);
                dialog.ShowDialog();

                RefleshDataView();
            }
        }

        private void btReceipt_Click(object sender, RoutedEventArgs e)
        {
            if (dataGrid.SelectedIndex == -1)
            {
                MessageBox.Show("Please select the relevant housing, and then add the receipt.");
                return;
            }
            tiReceipt.IsSelected = true;
        }

        public ApartmentView currentApartment;
        private void currentApartment_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (operation != Operation.Create)
            {
                operation = Operation.Update;
                ChangeWindowState();
            }
        }

        private const int RULELENGTH = 8;

        private int[] bitRule = new int[RULELENGTH];

        private bool getBitRule()
        {
            string errMessage = null;
            string str = "Select * From apartment_code WHERE id = 1";

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failed to read the room number naming.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            if (oleDT.Rows.Count < 1)
            {
                System.Windows.MessageBox.Show(
                    "Naming the room number is not set the initial value.",
                    "Failed to read the room number naming.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            DataRow r = oleDT.Rows[0];

            for (int i = 0; i < RULELENGTH; i++)
            {
                bitRule[i] = Convert.ToInt32(r[i + 1]);
            }

            return true;
        }

        private void OnApartmentCodeChanged(object sender, RoutedEventArgs e)
        {
            if (!(bool)checkAutoCode.IsChecked)
            {
                tbApartmentCode.Text = "";
                string ApartmentCode = "";

                for (int i = 0; i < RULELENGTH; i += 2)
                {
                    if (bitRule[i] != 0 && bitRule[i + 1] != 0)
                    {
                        switch (bitRule[i])
                        {
                            case 1:
                                if (cbApartmentBuilding.Text.Length == 0)
                                    return;
                                ApartmentCode += cbApartmentBuilding.Text;
                                break;
                            case 2:
                                if (cbApartmentFloor.Text.Length == 0)
                                    return;
                                if (cbApartmentFloor.Text.Length < bitRule[i + 1])
                                {
                                    for (int j = 0; j < bitRule[i + 1] - cbApartmentFloor.Text.Length; j++)
                                        ApartmentCode += "0";
                                }
                                ApartmentCode += cbApartmentFloor.Text;
                                break;
                            case 3:
                                if (cbApartmentUnit.Text.Length == 0)
                                    return;
                                ApartmentCode += cbApartmentUnit.Text;
                                break;
                            case 4:
                                if (cbApartmentSn.Text.Length == 0)
                                    return;
                                if (cbApartmentSn.Text.Length < bitRule[i + 1])
                                {
                                    for (int j = 0; j < bitRule[i + 1] - cbApartmentSn.Text.Length; j++)
                                        ApartmentCode += "0";
                                }
                                ApartmentCode += cbApartmentSn.Text;
                                break;
                        }
                    }
                }
                tbApartmentCode.Text = ApartmentCode;
                currentApartment.apartment_code = ApartmentCode;
            }
        }

        private void OnAreaPriceChanged(object sender, RoutedEventArgs e)
        {
            double buildArea;
            double publicArea;
            double area;
            double price;
            double decoratingPrice;

            if (cbApartmentBuildArea.Text.Length == 0 || 
                !Double.TryParse(cbApartmentBuildArea.Text, out buildArea))
            {
                cbApartmentBuildArea.Text = "0.00";
                buildArea = 0;
            }

            if (cbApartmentPublicArea.Text.Length == 0 || 
                !Double.TryParse(cbApartmentPublicArea.Text, out publicArea))
            {
                cbApartmentPublicArea.Text="0.00";
                publicArea = 0;
            }

            area = buildArea + publicArea;
            cbApartmentArea.Text = String.Format("{0:N2}", area);
            currentApartment.apartment_area = area;

            if (cbApartmentPrice.Text.Length == 0 ||
                !Double.TryParse(cbApartmentPrice.Text, out price))
            {
                cbApartmentPrice.Text = "0.00";
                price = 0;
            }

            cbApartmentTotal.Text = String.Format("{0:N2}",(area * price));
            currentApartment.apartment_total = area * price;

            if ((bool)checkApartmentDecorating.IsChecked)
            {
                if (cbDecoratingPrice.Text.Length == 0 ||
                !Double.TryParse(cbDecoratingPrice.Text, out decoratingPrice))
                {
                    cbDecoratingPrice.Text = "0.00";
                    decoratingPrice = 0;
                }

                cbDecoratingTotal.Text = String.Format("{0:N2}",(area * decoratingPrice));
                currentApartment.apartment_decorating_total = area * decoratingPrice;
            }
            else
            {
                cbDecoratingPrice.Text = "0.00";
                cbDecoratingTotal.Text = "0.00";

                currentApartment.apartment_decorating_price = 0;
                currentApartment.apartment_decorating_total = 0;
            }
        }

        private void ApartmentFinancialComputer(double AffirmanceDebateAmount, double ReceiptTotal)
        {
            currentApartment.apartment_payment_term = currentContract.contract_payment_terms;

            if (currentApartment.apartment_decorating)
            {
                currentApartment.apartment_accounts_due =
                    currentApartment.apartment_total + currentApartment.apartment_decorating_total;
            }
            else
            {
                currentApartment.apartment_accounts_due = currentApartment.apartment_total;
            }

            currentApartment.apartment_accounts_due =
                Math.Round(currentApartment.apartment_accounts_due, 2);

            currentApartment.apartment_rebate_amount = currentContract.debate_card_amount +
                AffirmanceDebateAmount + 
                (currentApartment.apartment_total - AffirmanceDebateAmount - currentContract.debate_card_amount) *
                (1 - currentContract.contract_debate_rate *
                currentContract.contract_payment_debate_rate *
                currentContract.manager_debate_rate);

            currentApartment.apartment_rebate_amount =
                Math.Round(currentApartment.apartment_rebate_amount, 2);

            if (currentApartment.apartment_payment_term == 2)
            {
                currentApartment.apartment_invoice_amount =
                    currentApartment.apartment_total - 
                    currentApartment.apartment_rebate_amount -
                    currentApartment.apartment_payment_bank_amount;
            }
            else
            {
                currentApartment.apartment_invoice_amount =
                    currentApartment.apartment_total - currentApartment.apartment_rebate_amount;
            }

            currentApartment.apartment_invoice_amount =
                Math.Round(currentApartment.apartment_invoice_amount,2);

            if (currentApartment.apartment_decorating)
            {
                currentApartment.apartment_payment_amount =
                    currentApartment.apartment_invoice_amount + 
                    currentApartment.apartment_decorating_total;
            }
            else
            {
                currentApartment.apartment_payment_amount =
                    currentApartment.apartment_invoice_amount;
            }

            currentApartment.apartment_payment_amount =
                Math.Round(currentApartment.apartment_payment_amount, 2);

            currentApartment.apartment_payment_paid_amount = Math.Round(ReceiptTotal, 2);

            currentApartment.apartment_payment_unpaid_amount =
                Math.Round(currentApartment.apartment_payment_amount - ReceiptTotal, 2);

            if (currentApartment.apartment_payment_unpaid_amount > 0)
            {
                currentApartment.apartment_payment_status = 1;
            }

            if (currentApartment.apartment_payment_paid_amount <= 0)
            {
                currentApartment.apartment_payment_status = 0;
            }

            if (currentApartment.apartment_payment_unpaid_amount <= 0)
            {
                currentApartment.apartment_payment_status = 2;
            }
        }

        private bool checkData()
        {
            int i;

            if (tbApartmentCode.Text == "")
            {
                MessageBox.Show("Please enter the room code.");
                tbApartmentCode.Focus();
                return false;
            }

            if (cbApartmentBuilding.Text == "")
            {
                MessageBox.Show("Please enter the building code.");
                cbApartmentBuilding.Focus();
                return false;
            }

            if (cbApartmentFloor.Text == "" || !Int32.TryParse(cbApartmentFloor.Text, out i))
            {
                MessageBox.Show("Please enter the floor.");
                cbApartmentFloor.Focus();
                return false;
            }

            if (cbApartmentSn.Text == "" || !Int32.TryParse(cbApartmentSn.Text, out i))
            {
                MessageBox.Show("Please enter the SN.");
                cbApartmentSn.Focus();
                return false;
            }

            if (operation == Operation.Create ||
                (operation == Operation.Update && 
                currentApartment.old_apartment_code != tbApartmentCode.Text))
            {
                string errMessage = null;
                string str = "SELECT * FROM apartments WHERE apartment_code = '";
                str += tbApartmentCode.Text + "'";

                DataTable oleDT;
                oleDT = libConn.AccdbConn.query(str, ref errMessage);

                if (errMessage != null)
                {
                    System.Windows.MessageBox.Show(
                        errMessage,
                        "Check whether there is room number error.",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return false;
                }

                if (oleDT.Rows.Count > 0)
                {
                    MessageBox.Show("The same room number there, try changing it.");
                    tbApartmentCode.Focus();
                    return false;
                }
            }

            return true;
        }

        private void RefleshApartmentEdit()
        {
            FillDataToComboBox(cbApartmentBuilding, "apartments", "apartment_building", false);
            FillDataToComboBox(cbApartmentFloor, "apartments", "apartment_floor", false);
            FillDataToComboBox(cbApartmentUnit, "apartments", "apartment_unit", false);
            FillDataToComboBox(cbApartmentSn, "apartments", "apartment_sn", false);
            FillDataToComboBox(cbApartmentBuildArea, "apartments", "apartment_built_area", false);
            FillDataToComboBox(cbApartmentPublicArea, "apartments", "apartment_public_area", false);
            FillDataToComboBox(cbApartmentArea, "apartments", "apartment_area", false);
            FillDataToComboBox(cbApartmentPrice, "apartments", "apartment_price", false);
            FillDataToComboBox(cbDecoratingPrice, "apartments", "apartment_decorating_price", false);
        }

        private void btSave_Click(object sender, RoutedEventArgs e)
        {
            errMessage = "";
            if (checkData())
            {
                if (operation == Operation.Create)
                {
                    errMessage = currentApartment.Insert();
                }
                else
                {
                    if (currentApartment.apartment_status == 2)
                    {
                        double affirmanceRebate;
                        double receiptTotal;
                        affirmanceRebate = receiptComputer.GetAffirmanceRebate();
                        receiptTotal = receiptComputer.GetReceiptTotal();
                        ApartmentFinancialComputer(affirmanceRebate, receiptTotal);
                    }
                    errMessage = currentApartment.Update();
                }

                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Save failed.", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else
                {
                    MessageBox.Show("Housing information stored successfully for " + currentApartment.apartment_code + ".",
                        "Successfully saved.", MessageBoxButton.OK, MessageBoxImage.Information);
                    operation = Operation.None;
                    ChangeWindowState();
                    tiList.IsSelected = true;
                    btFindClear_Click(sender, e);
                }
            }
        }

        private void btCancel_Click(object sender, RoutedEventArgs e)
        {
            operation = Operation.None;
            ChangeWindowState();
            tiList.IsSelected = true;
        }

        private bool contract_has_loaded = false;

        public ContractView currentContract;
        private void currentContract_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (operation == Operation.View)
            {
                operation = Operation.ContractUpdate;
                ChangeWindowState();
            }
        }

        private bool getContract(int apartment_id)
        {
            contract_has_loaded = false;

            errMessage = null;
            string str = "SELECT * FROM contract WHERE contract_status = 0 AND apartment_id = "
                + apartment_id;

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Get the current housing contract information error.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);

                return false;
            }

            if (oleDT.Rows.Count < 1)
            {
                return false;
            }

            try
            {
                DataRow r = oleDT.Rows[0];
                currentContract = new ContractView(r);
                currentContract.PropertyChanged += new PropertyChangedEventHandler(currentContract_PropertyChanged);
                tiContract.DataContext = currentContract;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Get the current housing contract information error.",
                    MessageBoxButton.OK, MessageBoxImage.Error);
                tiContract.IsEnabled = false;
                return false;
            }

            tbContractPaymentDebateRate.Text = String.Format("{0:N3}", currentContract.contract_payment_debate_rate);

            getManager();
            cbManagerName.Text = currentContract.manager_name;
            tbManagerDebateRate.Text = String.Format("{0:N3}",currentContract.manager_debate_rate);

            contract_has_loaded = true;
            return true;
        }

        private void cbContractPaymentTerms_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (contract_has_loaded)
            {
                tbContractPaymentDebateRate.Text = String.Format("{0:N3}", currentContract.payment_rate);
                currentContract.contract_payment_debate_rate = currentContract.payment_rate;
            }
        }

        private void tbContractPaymentDebateRate_LostFocus(object sender, RoutedEventArgs e)
        {
            double d = 1;
            if (tbContractPaymentDebateRate.Text == "" || !Double.TryParse(tbContractPaymentDebateRate.Text, out d) ||
                d < 0 || d > 2)
            {
                tbContractPaymentDebateRate.Text = String.Format("{0:N3}", 1);
            }
            currentContract.contract_payment_debate_rate = d;
        }

        private bool getManager()
        {
            cbManagerName.Items.Clear();

            string errMessage = null;
            string str = "Select * From manager";

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "An error occurred while reading the manager discounts.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            foreach (DataRow r in oleDT.Rows)
            {
                cbManagerName.Items.Add(new ManagerView()
                {
                    manager_id = Convert.ToInt32(r[0]),
                    manager_name = r[1].ToString().Replace("''", "'"),
                    manager_rebate_rate = Convert.ToDouble(r[2])
                });
            }
            return true;
        }

        private void cbManagerName_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (contract_has_loaded)
            {
                if (cbManagerName.SelectedIndex == -1)
                {
                    tbManagerDebateRate.Text = String.Format("{0:N3}", 1);

                    currentContract.manager_name = cbManagerName.Text;
                    currentContract.manager_debate_rate = 1;
                }
                else
                {
                    ManagerView mv = cbManagerName.SelectedItem as ManagerView;
                    if (mv != null)
                    {
                        tbManagerDebateRate.Text = String.Format("{0:N3}", mv.manager_rebate_rate);

                        currentContract.manager_name = mv.manager_name;
                        currentContract.manager_debate_rate = mv.manager_rebate_rate;
                    }
                }
            }
        }

        private void tbManagerDebateRate_LostFocus(object sender, RoutedEventArgs e)
        {
            double d = 1;
            if (tbManagerDebateRate.Text == "" || !Double.TryParse(tbManagerDebateRate.Text, out d) ||
                d < 0 || d > 2)
            {
                tbManagerDebateRate.Text = String.Format("{0:N3}", 1);
            }
            currentContract.manager_debate_rate = d;
        }

        private bool CheckContract()
        {
            double d;

            if (tbContractDebateRate.Text.Length == 0 ||
                !Double.TryParse(tbContractDebateRate.Text, out d) ||
                d > 10 || d <= 0)
            {
                MessageBox.Show("Please enter a reasonable value.\nValue must be greater than 0 and less than 10.");
                tbContractDebateRate.Focus();
                return false;
            }

            if (tbContractPaymentDebateRate.Text.Length == 0 ||
                !Double.TryParse(tbContractPaymentDebateRate.Text, out d) ||
                d > 10 || d <= 0)
            {
                MessageBox.Show("Please enter a reasonable value.\nValue must be greater than 0 and less than 10.");
                tbContractPaymentDebateRate.Focus();
                return false;
            }


            if (tbManagerDebateRate.Text.Length == 0 ||
                !Double.TryParse(tbManagerDebateRate.Text, out d) ||
                d > 10 || d <= 0)
            {
                MessageBox.Show("Please enter a reasonable value.\nValue must be greater than 0 and less than 10.");
                tbManagerDebateRate.Focus();
                return false;
            }

            if (tbDebateCardAmount.Text.Length == 0 ||
                !Double.TryParse(tbDebateCardAmount.Text, out d) ||
                d > 100000 || d < 0)
            {
                MessageBox.Show("Please enter a reasonable value.\nValue must be greater than 0 and less than 100000.");
                tbDebateCardAmount.Focus();
                return false;
            }

            return true;
        }

        private bool HasDeposited()
        {
            foreach (ReceiptView receipt in receiptDataGrid.Items)
            {
                if (receipt.receipt_type == 1 && receipt.receipt_status < 2)
                {
                    return true;
                }
            }

            return false;
        }

        private void btContractSave_Click(object sender, RoutedEventArgs e)
        {
            if (!CheckContract())
                return;

            if (operation == Operation.ContractCreate)
            {
                errMessage = currentContract.Insert();

                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Save the contract failed.", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                double affirmanceRebate;
                double receiptTotal;
                affirmanceRebate = receiptComputer.GetAffirmanceRebate();
                receiptTotal = receiptComputer.GetReceiptTotal();
                ApartmentFinancialComputer(affirmanceRebate,receiptTotal);

                currentApartment.apartment_status = 2;
                currentApartment.apartment_host_name = currentContract.contract_custom_name;
                currentApartment.apartment_host_contact = currentContract.contract_custom_contact;

                errMessage = currentApartment.Update();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Save the contract, the calculation of the Housing Finance and Accounting Information failed.",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
            else if (operation == Operation.ContractUpdate)
            {
                if (currentContract.contract_status == 1)
                {
                    MessageBoxResult result;
                    result = MessageBox.Show("Do you want the status of this contract is set to 'void' it?\nThis operation is equivalent to delete, and change the relevant state of the housing.",
                        "Save Contract", MessageBoxButton.OKCancel, MessageBoxImage.Question);

                    if (result == MessageBoxResult.Cancel)
                    {
                        return;
                    }
                }

                errMessage = currentContract.Update();

                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Save the contract failure", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                if (currentContract.contract_status == 0)
                {
                    double affirmanceRebate;
                    double receiptTotal;
                    affirmanceRebate = receiptComputer.GetAffirmanceRebate();
                    receiptTotal = receiptComputer.GetReceiptTotal();
                    ApartmentFinancialComputer(affirmanceRebate, receiptTotal);
                }
                else
                {
                    currentApartment.apartment_status = 0;

                    currentApartment.apartment_rebate_amount = 0;
                    currentApartment.apartment_accounts_due = 0;
                    currentApartment.apartment_invoice_amount = 0;
                    currentApartment.apartment_payment_term = 0;
                    currentApartment.apartment_payment_status = 0;
                    currentApartment.apartment_payment_amount = 0;
                    currentApartment.apartment_payment_paid_amount = 0;
                    currentApartment.apartment_payment_unpaid_amount = 0;
                    currentApartment.apartment_payment_bank_amount = 0;
                    currentApartment.apartment_payment_bank_income = 0;
                    currentApartment.apartment_host_name = "";
                    currentApartment.apartment_host_contact = "";
                }

                if ((currentContract.contract_status == 1) && HasDeposited())
                    currentApartment.apartment_status = 1;

                errMessage = currentApartment.Update();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Save the contract, the calculation of the Housing Finance and Accounting Information failed.",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
            else
            {
                return;
            }

            MessageBox.Show("Save the code as " + currentApartment.apartment_code + " contract information successful.",
                "Save a successful contract", MessageBoxButton.OK, MessageBoxImage.Information);

            RefleshDataView();
            operation = Operation.None;
            ChangeWindowState();
            tiList.IsSelected = true;
            btFindClear_Click(sender, e);
        }

        private void btContractCancel_Click(object sender, RoutedEventArgs e)
        {
            operation = Operation.None;
            ChangeWindowState();
            tiList.IsSelected = true;
        }

        private ReceiptComputer receiptComputer;

        private bool getReceipt(int apartment_id)
        {
            receiptComputer = new ReceiptComputer();

            errMessage = null;
            string str = "SELECT * FROM receipt WHERE apartment_id = "
                + apartment_id;

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Receipt information for the current housing error.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            ObservableCollection<ReceiptView> receipts = new ObservableCollection<ReceiptView>();

            try
            {
                foreach (DataRow r in oleDT.Rows)
                {
                    ReceiptView receipt = new ReceiptView(r);
                    receipts.Add(receipt);
                    receiptComputer.Add(receipt);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Receipt information for the current housing error.", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            receiptDataGrid.DataContext = receipts;
            return true;
        }

        private bool getReceipt(AffirmanceView gData, ref ReceiptView receipt)
        {
            string errMessage = null;
            string str = "SELECT * FROM receipt WHERE receipt_id = "
                + gData.receipt_id;

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Failure to obtain a receipt number.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            if (oleDT.Rows.Count == 0)
            {
                System.Windows.MessageBox.Show(
                    "Can not find the receipt.",
                    "Save failed",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Stop);
                return false;
            }

            DataRow r = oleDT.Rows[0];
            receipt = new ReceiptView(r);
            return true;
        }

        private bool updateData(AffirmanceView data)
        {
            string errMessage = null;

            string str = "UPDATE affirmance SET affirmance_status = " + data.affirmance_status + ", ";
            str += "receipt_code = '" + data.receipt_code + "', ";
            str += "affirmance_amount = " + data.affirmance_amount + ", ";
            str += "affirmance_rule_type = '" + data.affirmance_rule_type.Replace("'", "''") + "', ";
            str += "affirmance_rule_rebate_amount = " + data.affirmance_rule_rebate_amount + ", ";
            str += "affirmance_custom_name = '" + data.affirmance_custom_name.Replace("'", "''") + "', ";
            str += "affirmance_custom_contact = '" + data.affirmance_custom_contact.Replace("'", "''") + "', ";
            str += "affirmance_modify_date = '" + DateTime.Now.ToString() + "' ";
            str += "WHERE affirmance_id = " + data.affirmance_id;

            libConn.AccdbConn.exec(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Data failed to modify affirmance.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }
            MessageBox.Show("Affirmance to modify the data successfully.");
            return true;
        }

        private bool updateAffirmance(int receipt_id)
        {
            string errMessage = null;

            string str = "UPDATE affirmance SET affirmance_status = 0, ";
            str += "affirmance_modify_date = '" + DateTime.Now.ToString() + "' ";
            str += "WHERE receipt_id = " + receipt_id;

            libConn.AccdbConn.exec(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Modify the record affirmance to fail.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }
            return true;
        }

        private bool deleteDeposit(int receipt_id)
        {
            string errMessage = null;
            string str = "DELETE FROM deposit WHERE receipt_id = " + receipt_id;

            libConn.AccdbConn.exec(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Delete order record failed.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }
            return true;
        }

        private void UpdateApartmentWithReceiptChanged()
        {
            getReceipt(currentApartment.apartment_id);

            if (currentApartment.apartment_status == 2)
            {
                double affirmanceRebate;
                double receiptTotal;

                affirmanceRebate = receiptComputer.GetAffirmanceRebate();
                receiptTotal = receiptComputer.GetReceiptTotal();
                ApartmentFinancialComputer(affirmanceRebate, receiptTotal);

                errMessage = currentApartment.Update();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Add receipts failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                RefleshDataView();
            }

            operation = Operation.View;
            ChangeWindowState();
        }

        private void btReceiptAffirmance_Click(object sender, RoutedEventArgs e)
        {
            if (currentApartment.apartment_status != 2)
            {
                MessageBox.Show("Please add the contract, and then add the relevant receipts.");
                return;
            }

            if (receiptComputer.TypeGrid[0] != 0)
            {
                MessageBox.Show("Affirmance have been associated with a receipt.");
                return;
            }

            AffirmanceView affirmance = new AffirmanceView();
            AffirmanceSelector dialog = new AffirmanceSelector(affirmance);
            dialog.ShowDialog();

            if (affirmance.affirmance_id != 0)
            {
                affirmance.affirmance_status = 1;
                if (!updateData(affirmance))
                    return;

                ReceiptView receipt = new ReceiptView();
                if (!getReceipt(affirmance, ref receipt))
                    return;

                receipt.apartment_id = currentApartment.apartment_id;
                
                errMessage = receipt.Update();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Add receipts failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                
                UpdateApartmentWithReceiptChanged();
            }
        }

        private void btReceiptApartment_Click(object sender, RoutedEventArgs e)
        {
            if (currentApartment.apartment_status != 2)
            {
                MessageBox.Show("Please add the contract, and then add the relevant receipts.");
                return;
            }

            ReceiptView receipt = new ReceiptView();
            receipt.apartment_id = currentApartment.apartment_id;
            receipt.receipt_type = 2;

            receipt.receipt_card_amount = currentApartment.apartment_payment_unpaid_amount;
            
            if (currentApartment.apartment_decorating)
            {
                if (receiptComputer.TypeGrid[3] == 0)
                {
                    receipt.receipt_card_amount -= currentApartment.apartment_decorating_total;
                }
                else
                {
                    receipt.receipt_card_amount = 
                        currentApartment.apartment_payment_amount - receiptComputer.GetReceiptTotal();
                }
            }

            receipt.receipt_custom_name = currentApartment.apartment_host_name;

            ReceiptEdit dialog = new ReceiptEdit(receipt);
            dialog.ShowDialog();

            if (receipt.has_changed)
            {
                errMessage = receipt.Insert();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Add receipts failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
            getReceipt(currentApartment.apartment_id);

            UpdateApartmentWithReceiptChanged();
        }

        private void btReceiptDecorating_Click(object sender, RoutedEventArgs e)
        {
            if (currentApartment.apartment_status != 2)
            {
                MessageBox.Show("Please add the contract, and then add the relevant receipts.");
                return;
            }

            if (!currentApartment.apartment_decorating)
            {
                MessageBox.Show("The house is not fitting costs.");
                return;
            }

            ReceiptView receipt = new ReceiptView();
            receipt.apartment_id = currentApartment.apartment_id;
            receipt.receipt_type = 3;
            receipt.receipt_custom_name = currentApartment.apartment_host_name;

            receipt.receipt_card_amount = currentApartment.apartment_decorating_total;

            ReceiptEdit dialog = new ReceiptEdit(receipt);
            dialog.ShowDialog();

            if (receipt.has_changed)
            {
                errMessage = receipt.Insert();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Add receipts failed", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }

            UpdateApartmentWithReceiptChanged();
        }

        private void btReceiptView_Click(object sender, RoutedEventArgs e)
        {
            if (currentApartment.apartment_status != 2)
            {
                MessageBox.Show("Please add the contract, and then add the relevant receipts.");
                return;
            }

            if (receiptDataGrid.SelectedIndex == -1)
            {
                MessageBox.Show("Please select the relevant receipts.");
                return;
            }

            ReceiptView receipt_clone;
            ReceiptView receipt = receiptDataGrid.SelectedItem as ReceiptView;
            if (receipt == null)
                return;
            receipt_clone = (ReceiptView)receipt.Clone();

            ReceiptEdit dialog = new ReceiptEdit(receipt_clone);
            dialog.ShowDialog();

            if (receipt_clone.has_changed)
            {
                errMessage = receipt_clone.Update();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Modify the receipt failed.", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }

            UpdateApartmentWithReceiptChanged();
        }

        private void receiptDataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (currentApartment.apartment_status != 2)
            {
                MessageBox.Show("Please add the contract, then modify the relevant receipts.");
                return;
            }

            if (receiptDataGrid.SelectedIndex == -1)
            {
                MessageBox.Show("Please select the relevant receipts.");
                return;
            }

            ReceiptView receipt_clone;
            ReceiptView receipt = receiptDataGrid.SelectedItem as ReceiptView;
            if (receipt == null)
                return;
            receipt_clone = (ReceiptView)receipt.Clone();

            ReceiptEdit dialog = new ReceiptEdit(receipt_clone);
            dialog.ShowDialog();

            if (receipt_clone.has_changed)
            {
                errMessage = receipt_clone.Update();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Modify the receipt failed.", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }

            UpdateApartmentWithReceiptChanged();
        }

        private void btReceiptRecover_Click(object sender, RoutedEventArgs e)
        {
            if (receiptDataGrid.SelectedIndex == -1)
            {
                MessageBox.Show("Please select a receipt information.");
                return;
            }

            ReceiptView receipt = receiptDataGrid.SelectedItem as ReceiptView;

            if (receipt != null && receipt.receipt_status == 0)
            {
                receipt.receipt_status = 1;
                errMessage = receipt.Update();
                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Recycling affirmance receipt failed.", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else
                {
                    getReceipt(currentApartment.apartment_id);
                    MessageBox.Show("Receipt of a successful recovery of affirmance.", "Successful", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
        }

        private void btReceiptDelete_Click(object sender, RoutedEventArgs e)
        {
            if (receiptDataGrid.SelectedIndex == -1)
            {
                MessageBox.Show("Please select the relevant receipts.");
                return;
            }

            ReceiptView receipt = receiptDataGrid.SelectedItem as ReceiptView;
            if (receipt == null)
            {
                return;
            }

            if (MessageBox.Show("Are you sure you want to delete the selected receipt?\nThis action can not be restored.",
                "Delete receipt", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK)
            {
                if (receipt.receipt_type == 0)
                {
                    if (!updateAffirmance(receipt.receipt_id))
                    {
                        return;
                    }

                    receipt.receipt_status = 0;
                    receipt.apartment_id = 0;

                    errMessage = receipt.Update();
                }
                else
                {
                    if (receipt.receipt_type == 1)
                    {
                        if (currentApartment.apartment_status == 1)
                        {
                            currentApartment.apartment_status = 0;

                            errMessage = currentApartment.Update();
                            if (errMessage != "")
                            {
                                MessageBox.Show(errMessage, "Housing status change failed.", MessageBoxButton.OK, MessageBoxImage.Error);
                                return;
                            }

                            RefleshDataView();
                        }

                        if (!deleteDeposit(receipt.receipt_id))
                        {
                            return;
                        }
                    }

                    errMessage = receipt.Delete();
                }

                if (errMessage != "")
                {
                    MessageBox.Show(errMessage, "Remove receipt failed.", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                UpdateApartmentWithReceiptChanged();
            }
        }

        private bool getInvoice(int apartment_id)
        {
            errMessage = null;
            string str = "SELECT * FROM invoice WHERE apartment_id = "
                + apartment_id;

            DataTable oleDT;
            oleDT = libConn.AccdbConn.query(str, ref errMessage);

            if (errMessage != null)
            {
                System.Windows.MessageBox.Show(
                    errMessage,
                    "Invoice information for the current housing error.",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
                return false;
            }

            ObservableCollection<InvoiceView> invoicies = new ObservableCollection<InvoiceView>();

            try
            {
                foreach (DataRow r in oleDT.Rows)
                {
                    invoicies.Add(new InvoiceView(r));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Invoice information for the current housing error.", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }


            invoiceDataGrid.DataContext = invoicies;
            return true;
        }

        private void invoiceDataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (invoiceDataGrid.SelectedIndex != -1)
            {
                InvoiceView invoice = invoiceDataGrid.SelectedItem as InvoiceView;

                if (invoice != null)
                {
                    InvoiceEdit dialog = new InvoiceEdit(invoice);

                    dialog.ShowDialog();
                    getInvoice(currentApartment.apartment_id);
                }
            }
        }

        private void btInvoiceAdd_Click(object sender, RoutedEventArgs e)
        {
            if (dataGrid.SelectedIndex == -1 && operation == Operation.None)
            {
                MessageBox.Show("Please select the house, and then add the invoice.");
                return;
            }

            InvoiceEdit dialog = new InvoiceEdit(currentApartment.apartment_id,
                currentApartment.apartment_invoice_amount,
                currentApartment.apartment_host_name);

            dialog.ShowDialog();
            getInvoice(currentApartment.apartment_id);
        }

        private void btInvoiceView_Click(object sender, RoutedEventArgs e)
        {
            if (invoiceDataGrid.SelectedIndex != -1)
            {
                InvoiceView invoice = invoiceDataGrid.SelectedItem as InvoiceView;

                if (invoice != null)
                {
                    InvoiceEdit dialog = new InvoiceEdit(invoice);

                    dialog.ShowDialog();
                    getInvoice(currentApartment.apartment_id);
                }
            }
            else
            {
                MessageBox.Show("Please select an invoice information.");
            }
        }
    }
}
